﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using YJKGeometryFuncs;

namespace YJKPatternSign.StairsRoomPlanSign.ModelLayer
{
	public class BoundingBoxPakcer
	{
		public List<XYZ> LstDriection
		{
			get
			{
				return this.m_lstDriection;
			}
		}

		public List<XYZ> LstPoint
		{
			get
			{
				return this.m_lstPoints;
			}
		}

		public List<Line> LstBoundLine
		{
			get
			{
				return this.m_lstBoundLine;
			}
		}

		public BoundingBoxPakcer(XYZ minPoint, XYZ maxPoint, double useZ, List<XYZ> lstDriection)
		{
			this.m_dUseZ = useZ;
			this.makeLstPoints(minPoint, maxPoint, this.m_dUseZ, lstDriection);
		}

		public BoundingBoxPakcer(BoundingBoxXYZ inputBoundingBox, double useZ, List<XYZ> lstDriection)
		{
			Transform transform = inputBoundingBox.Transform;
			XYZ maxPoint = Geometry.TransformPoint(inputBoundingBox.Max, inputBoundingBox.Transform);
			XYZ minPoint = Geometry.TransformPoint(inputBoundingBox.Min, inputBoundingBox.Transform);
			this.m_dUseZ = useZ;
			this.makeLstPoints(minPoint, maxPoint, this.m_dUseZ, lstDriection);
		}

		public bool moveBound(double moveValue)
		{
			if (0.0 > moveValue && Math.Abs(moveValue) > 2.0 * Math.Min(this.m_dWidth, this.m_dHight))
			{
				return false;
			}
			XYZ xyz = this.m_lstPoints[0].Add(this.m_lstDriection[0].Multiply(moveValue));
			xyz = xyz.Add(this.m_lstDriection[1].Multiply(moveValue));
			XYZ xyz2 = this.m_lstPoints[2].Add((-this.m_lstDriection[0]).Multiply(moveValue));
			xyz2 = xyz2.Add((-this.m_lstDriection[1]).Multiply(moveValue));
			this.makeLstPoints(xyz, xyz2, this.m_dUseZ, this.m_lstDriection);
			return true;
		}

		public bool IfPointInPacker(XYZ inputPoint)
		{
			XYZ xyz = Utility.PointAtUseZ(inputPoint, this.m_dUseZ);
			List<XYZ> list = new List<XYZ>();
			foreach (XYZ xyz2 in this.m_lstPoints)
			{
				list.Add(xyz.Add(-xyz2).Normalize());
			}
			double num = 0.0;
			for (int i = 0; i < list.Count; i++)
			{
				if (i != list.Count - 1)
				{
					num += list[i].AngleTo(list[i + 1]);
				}
				else
				{
					num += list[i].AngleTo(list[0]);
				}
			}
			return Math.Abs(num - Math.PI*2) <= 0.01;
		}

		private void makeLstPoints(XYZ minPoint, XYZ maxPoint, double useZ, List<XYZ> lstDriection)
		{
			if (minPoint == null || maxPoint == null || lstDriection == null || 2 > lstDriection.Count || minPoint.IsAlmostEqualTo(maxPoint))
			{
				throw new ArgumentException();
			}
			XYZ xyz = Utility.PointAtUseZ(minPoint, useZ);
			XYZ xyz2 = Utility.PointAtUseZ(maxPoint, useZ);
			XYZ xyz3 = Utility.PointAtUseZ(lstDriection[0], 0.0).Normalize();
			XYZ xyz4 = Utility.PointAtUseZ(lstDriection[1], 0.0).Normalize();
			XYZ xyz5 = Utility.IntersectionPoint(xyz, xyz2, xyz4, -xyz3);
			XYZ xyz6 = Utility.IntersectionPoint(xyz, xyz2, xyz3, -xyz4);
			if (this.m_lstDriection == null)
			{
				this.m_lstDriection = new List<XYZ>();
			}
			this.m_lstDriection.Clear();
			this.m_lstDriection.AddRange(new XYZ[]
			{
				xyz3,
				xyz4
			});
			if (this.m_lstPoints == null)
			{
				this.m_lstPoints = new List<XYZ>();
			}
			this.m_lstPoints.Clear();
			this.m_lstPoints.AddRange(new XYZ[]
			{
				xyz,
				xyz5,
				xyz2,
				xyz6
			});
			this.m_dWidth = xyz.DistanceTo(xyz6);
			this.m_dHight = xyz.DistanceTo(xyz5);
			this.m_lstBoundLine = Utility.GetALoopLine(this.m_lstPoints);
		}

		private List<XYZ> m_lstDriection;

		private List<XYZ> m_lstPoints;

		private List<Line> m_lstBoundLine;

		private double m_dUseZ;

		private double m_dWidth;

		private double m_dHight;
	}
}
